package controllers

import (
	"encoding/json"
	"errors"
	"strings"
	"time"
	"strconv"

	"gitee.com/lzqysoft/ga_wz_backend/models"
	"github.com/astaxie/beego"
)

// SfCaseController operations for SfCase
type SfCaseController struct {
	CommonController
}

// URLMapping ...
func (c *SfCaseController) URLMapping() {
	c.Mapping("Post", c.Post)
	c.Mapping("GetOne", c.GetOne)
	c.Mapping("GetAll", c.GetAll)
	c.Mapping("Put", c.Put)
	c.Mapping("Delete", c.Delete)
	c.Mapping("PostCase", c.PostCase)
	c.Mapping("DeleteCaseList", c.DeleteCaseList)
	c.Mapping("AdditionCase", c.AdditionCase)
	c.Mapping("GetSfCaseById", c.GetSfCaseById)
	c.Mapping("GetCaseItemsByCase", c.GetCaseItemsByCase)
	c.Mapping("GetSfCaseByType", c.GetSfCaseByType)
	c.Mapping("QueryAllCase", c.QueryAllCase)
	c.Mapping("GetAllCaseForExport", c.GetAllCaseForExport)
	c.Mapping("DelCaseRealated", c.DelCaseRealated)
}

// Post ...
// @Title Post
// @Description create SfCase
// @Param	body		body 	models.SfCase	true		"body for SfCase content"
// @Success 201 {int} models.SfCase
// @Failure 403 body is empty
// @router / [post]
func (c *SfCaseController) Post() {
	var v models.SfCase
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &v); err == nil {
		if _, err := models.AddSfCase(&v); err == nil {
			c.Ctx.Output.SetStatus(201)
			c.Data["json"] = v
		} else {
			c.Data["json"] = err.Error()
		}
	} else {
		c.Data["json"] = err.Error()
	}
	c.ServeJSON()
}

// GetOne ...
// @Title Get One
// @Description get SfCase by id
// @Param	id		path 	string	true		"The key for staticblock"
// @Success 200 {object} models.SfCase
// @Failure 403 :id is empty
// @router /:id [get]
func (c *SfCaseController) GetOne() {
	idStr := c.Ctx.Input.Param(":id")
	//id, _ := strconv.Atoi(idStr)
	v, err := models.GetSfCaseById(idStr)
	if err != nil {
		c.Data["json"] = err.Error()
	} else {
		c.Data["json"] = v
	}
	c.ServeJSON()
}

// GetAll ...
// @Title Get All
// @Description get SfCase
// @Param	query	query	string	false	"Filter. e.g. col1:v1,col2:v2 ..."
// @Param	fields	query	string	false	"Fields returned. e.g. col1,col2 ..."
// @Param	sortby	query	string	false	"Sorted-by fields. e.g. col1,col2 ..."
// @Param	order	query	string	false	"Order corresponding to each sortby field, if single value, apply to all sortby fields. e.g. desc,asc ..."
// @Param	limit	query	string	false	"Limit the size of result set. Must be an integer"
// @Param	offset	query	string	false	"Start position of result set. Must be an integer"
// @Success 200 {object} models.SfCase
// @Failure 403
// @router / [get]
func (c *SfCaseController) GetAll() {
	var fields []string
	var sortby []string
	var order []string
	var query = make(map[string]string)
	var limit int64 = 10
	var offset int64

	// fields: col1,col2,entity.col3
	if v := c.GetString("fields"); v != "" {
		fields = strings.Split(v, ",")
	}
	// limit: 10 (default is 10)
	if v, err := c.GetInt64("limit"); err == nil {
		limit = v
	}
	// offset: 0 (default is 0)
	if v, err := c.GetInt64("offset"); err == nil {
		offset = v
	}
	// sortby: col1,col2
	if v := c.GetString("sortby"); v != "" {
		sortby = strings.Split(v, ",")
	}
	// order: desc,asc
	if v := c.GetString("order"); v != "" {
		order = strings.Split(v, ",")
	}
	// query: k:v,k:v
	if v := c.GetString("query"); v != "" {
		for _, cond := range strings.Split(v, ",") {
			kv := strings.SplitN(cond, ":", 2)
			if len(kv) != 2 {
				c.Data["json"] = errors.New("Error: invalid query key/value pair")
				c.ServeJSON()
				return
			}
			k, v := kv[0], kv[1]
			query[k] = v
		}
	}

	l, err := models.GetAllSfCase(query, fields, sortby, order, offset, limit)
	if err != nil {
		c.Data["json"] = err.Error()
	} else {
		c.Data["json"] = l
	}
	c.ServeJSON()
}

// Put ...
// @Title Put
// @Description update the SfCase
// @Param	id		path 	string	true		"The id you want to update"
// @Param	body		body 	models.SfCase	true		"body for SfCase content"
// @Success 200 {object} models.SfCase
// @Failure 403 :id is not int
// @router /:id [put]
func (c *SfCaseController) Put() {
	idStr := c.Ctx.Input.Param(":id")
	//id, _ := strconv.Atoi(idStr)
	v := models.SfCase{Id: idStr}
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &v); err == nil {
		if err := models.UpdateSfCaseById(&v); err == nil {
			c.Data["json"] = "OK"
		} else {
			c.Data["json"] = err.Error()
		}
	} else {
		c.Data["json"] = err.Error()
	}
	c.ServeJSON()
}

// Delete ...
// @Title Delete
// @Description delete the SfCase
// @Param	id		path 	string	true		"The id you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 id is empty
// @router /:id [delete]
func (c *SfCaseController) Delete() {
	idStr := c.Ctx.Input.Param(":id")
	//id, _ := strconv.Atoi(idStr)
	if err := models.DeleteSfCase(idStr); err == nil {
		c.Data["json"] = "OK"
	} else {
		c.Data["json"] = err.Error()
	}
	c.ServeJSON()
}

// PostCase ...
// @Title PostCase
// @Description PostCase
// @Param	body		body 	models.SfCase	true		"body for SfCase content"
// @Success 201 {int} models.SfCase
// @Failure 403 body is empty
// @router /PostCase [post]
func (c *SfCaseController) PostCase() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var sf SfCaseModel
	if err = json.Unmarshal(tdata, &sf); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	beego.Debug(sf)
	// 预约流程， 创建SfCase，sfCaseItem
	sfcase := models.GenSfCase()
	sfcase.Updater = user.Abbr
	sfcase.Creater = user.Abbr
	sfcase.Cid = user.Id
	sfcase.Uid = user.Id
	sfcase.Title = sf.Title
	sfcase.No = sf.No
	sfcase.JyType = sf.JdType
	sfcase.Category = sf.Category
	sfcase.Phone = sf.Phone
	sfcase.DeptId = user.Dept[0].Id
	sfcase.DeptName = user.Dept[0].Name
	sfcase.AppointTime = sf.Date
	sfcase.First = sf.First
	if sf.IsAdditional {
		// 如果是补充送检，锁定原case
		sfcase.IsAdditional = 1
		sfcase.AdditionalId = sf.CaseId
		sourceSfcaseo, _ := models.GetSfCaseById(sf.CaseId)
		sourceSfcaseo.Lock = 1
		models.UpdateSfCaseById(sourceSfcaseo)
	}
	beego.Debug("TYPE is: ", sfcase.JyType)
	_, err = models.AddSfCase(sfcase)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	item := models.GenSfCaseItem();
	item.Creater = user.Abbr
	item.Cid = user.Id
	item.Updater = user.Abbr
	item.Uid = user.Id
	item.JyType = sf.JdType
	item.Remark = sf.Info
	item.First = sf.First
	item.Category = sf.Category
	item.OrginizationId = user.Organization.Id
	item.DeptId = user.Dept[0].Id
	item.DeptName = user.Dept[0].Name
	item.UserId = user.Id
	item.UserName = user.Abbr
	item.SfCaseId = sfcase.Id
	item.AppointTime = sf.Date

	_, err = models.AddSfCaseItem(item)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	c.RetSuccess(nil)

}

// GetSfCases ...
// @Title GetSfCases
// @Description GetSfCases
// @Success 200 {string} get success!
// @Failure 403 no date
// @router /GetSfCases [get]
func (c *SfCaseController) GetSfCases() {
	user := c.User
	res, err := models.GetSfCaseByUserIdAndStatus(user.Id)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(res)
}

func (c *SfCaseController) GetFinsish()  {
	user := c.User
	res, err := models.GetSfCaseByUserIdAndStatus(user.Id)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(res)
}

// SfCase 预约数据模型
type SfCaseModel struct {
	CaseId       string
	IsAdditional bool
	JdType       int
	Category     int
	First        int
	Phone        string
	Date         time.Time
	Info         string
	Title        string
	No           string
}

// DeleteCaseList ...
// @Title DeleteCaseList
// @Description DeleteCaseList
// @Success 200 {string} get success!
// @Failure 403 no date
// @router /DeleteCaseList [post]
func (c *SfCaseController) DeleteCaseList() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		c.RetError(ErrToken)
	}
	var ids []string
	if err = json.Unmarshal(tdata, &ids); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	if err = models.SoftDeleteSfCase(user, ids); err !=nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	c.RetSuccess(nil)
}

// AdditionCase ...
// @Title AdditionCase
// @Description AdditionCase
// @Param	body	body 	map	 true
// @Success 201 {int}  null
// @Failure 403 body is empty
// @router /AdditionCase [post]
func (c *SfCaseController) AdditionCase() {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		c.RetError(ErrToken)
	}
	form := make(map[string]interface{})
	json.Unmarshal(tdata, &form)
	beego.Debug(form)
	c.RetSuccess(nil)
}

// GetSfCaseById ...
// @Title GetSfCaseById
// @Description GetSfCaseById
// @Param	body	body 	map	 true
// @Success 201 {int}  null
// @Failure 403 body is empty
// @router /GetSfCaseById [post]
func (c *SfCaseController) GetSfCaseById() {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		c.RetError(ErrToken)
	}
	params := make(map[string]interface{})
	if err = json.Unmarshal(tdata, &params); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	id, ok := params["Id"]
	if !ok {
		beego.Debug(ErrInputData)
	}
	if v, err :=  models.GetSfCaseById(id.(string)); err == nil {
		c.RetSuccess(v)
	} else {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
}

// GetSfCaseByType ...
// @Title GetSfCaseByType
// @Description GetSfCaseByType
// @Param	body	body 	map	 true
// @Success 201 {int}  null
// @Failure 403 body is empty
// @router /GetSfCaseByType [post]
func (c *SfCaseController) GetSfCaseByType() {
	user := c.User
	tdata, err := c.AesDecode(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}

	fdata, _ := tdata.(map[string]interface{})
	frist := fdata["Type"].(string)
	fristType,_ := strconv.Atoi(frist)
	//beego.Debug(fdata)
	res, err := models.GetSfCaseByUserIdAndType(user.Id, fristType)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(res)
}
// GetCaseItemsByCase ...
// @Title GetCaseItemsByCase
// @Description GetCaseItemsByCase
// @Param	body		body 	models.SfCaseItem
// @Success 201 {int} models.SfCaseItem
// @Failure 403 id is empty
// @router /GetCaseItemsByCase/:id [get]
func (c *SfCaseController) GetCaseItemsByCase() {
	//user := c.User
	id := c.Ctx.Input.Param(":id")
	if res, err := models.GetSfCaseItemsBySfCase(id); err == nil {
		c.RetSuccess(res)
	} else {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}

}

// QueryAllCase ...
// @Title QueryAllCase
// @Description QueryAllCase
// @Success 201 {int} models.QueryAllCase
// @Failure 403 id is empty
// @router /QueryAllCase/:page [get]
func (c *SfCaseController) QueryAllCase() {
	id := c.Ctx.Input.Param(":page")
	offset, err := strconv.Atoi(id)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	result := make(map[string]interface{})

	if total, res, err := models.GetLegalCase(offset-1); err == nil {
		//beego.Debug(err, res)
		result["total"] = total
		result["res"] = res
		c.RetSuccess(result)
	} else {
		beego.Debug(err, res)
		c.RetError(ErrInputData)
	}
}

// GetAllCase ...
// @Title GetAllCase
// @Description GetAllCase
// @Failure 403 id is empty
// @router /GetAllCaseForExport [get]
func (c *SfCaseController) GetAllCaseForExport() {
	res, err := models.GetALlCase()
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrDisk)
	}
	//beego.Debug(res)
	c.RetSuccess(res)
}


// DelCaseRealated ...
// @Title DelCaseRealated
// @Description DelCaseRealated
// @Failure 403 id is empty
// @router /DelCaseRealated [post]
func (c *SfCaseController) DelCaseRealated () {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		c.RetError(ErrToken)
	}
	var sfcase models.SfCase
	if err = json.Unmarshal(tdata, &sfcase); err != nil {
		c.RetError(ErrInputData)
	}
	if err = models.DelSfCaseRelated(sfcase); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	c.RetSuccess(nil)
}